package org.myproject.persistence;

import org.hibernate.HibernateException;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.event.PreInsertEventListener;
import org.hibernate.event.PreUpdateEventListener;
import org.myproject.persistence.event.PersistenceEvent;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean;

/**
 * Hibernate session factory bean.
 * 
 * Features:
 * <ul>
 * <li>Broadcasts {@link PersistenceEvent}s into spring application context</li>
 * </ul>
 * 
 * @author ivaynberg
 * 
 */
public class HibernateSessionFactoryBean extends AnnotationSessionFactoryBean
		implements ApplicationContextAware {
	private ApplicationContext applicationContext;

	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		this.applicationContext = applicationContext;
	}

	@Override
	protected void postProcessAnnotationConfiguration(
			AnnotationConfiguration config) throws HibernateException {
		super.postProcessAnnotationConfiguration(config);

		if (applicationContext == null) {
			throw new IllegalStateException("ApplicationContext was not set");
		}

		PersistenceEventBroadcaster broadcaster = new PersistenceEventBroadcaster(
				applicationContext);

		config.setListeners("pre-insert",
				new PreInsertEventListener[] { broadcaster });
		config.setListeners("pre-update",
				new PreUpdateEventListener[] { broadcaster });

	}
}
